﻿using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Collections.Generic;

namespace PasswordProvider.ObjectModel
{
    [DataContract]
    public sealed class EncryptedValue : DataObject
    {
        public EncryptedValue()
        {
            CreationDate = DateTime.Now;
        }
        
        internal static Cipher Ciypher { get; set; }

        #region Public Properties

        public bool HasValue 
        {
            get 
            { 
                return Value != null && Value.Length > 0; 
            }
        }

        [DataMember]
        public DateTime CreationDate { get; set; }

        [DataMember]
        public DateTime LastAccessDate
        {
            get { return _lastAccessDate; }
            private set { SetPropertyValue(value, ref _lastAccessDate, "LastAccessDate"); } 
        } DateTime _lastAccessDate;

        [DataMember]
        public int AccessCount
        {
            get { return _accessCount; }
            private set { SetPropertyValue(value, ref _accessCount, "AccessCount"); }
        } int _accessCount;

        #endregion // Public Data Members

        #region Private Data Members
        
        [DataMember]
        private byte[] Salt { get; set; }

        [DataMember]
        private byte[] Value { get; set; }

        
        #endregion

        #region Public and Internal Methods

        internal ProtectedString GetValueDecrypted(Cipher cipher)
        {
            if (Value != null && Salt != null)
            {
                ProtectedString value = cipher.DecryptValue(Value, Salt);

                AccessCount++;
                LastAccessDate = DateTime.Now;

                return value;
            }

            return null;
        }

        internal void SetValueEncrypted(ProtectedString value, Cipher cipher)
        {
            var pair = cipher.EncryptValue(value);
            Salt = pair.Key;
            Value = pair.Value;
            OnPropertyChanged("Value");
        }

        #endregion

        #region Internal

        internal void Copy(EncryptedValue encryptedValue)
        {
            Salt = encryptedValue.Salt;
            Value = encryptedValue.Value;
            LastAccessDate = encryptedValue.LastAccessDate;
            CreationDate = encryptedValue.CreationDate;
            AccessCount = encryptedValue.AccessCount;
        }

        #endregion

    }
}
